/**
 * 雪花ID生成器
 * 基于时间戳、机器ID和序列号生成18位纯数字唯一ID
 */

// 机器ID (0-31)
const MACHINE_ID = Math.floor(Math.random() * 32);
// 序列号 (0-4095)
let sequence = 0;
// 上次生成ID的时间戳
let lastTimestamp = -1;

// 起始时间戳 (2024-01-01 00:00:00 UTC)
const EPOCH = 1704067200000;

/**
 * 生成18位纯数字雪花ID（不以0开头）
 * @returns {string} 18位雪花ID字符串
 */
export function generateSnowflakeId() {
  let timestamp = Date.now();
  
  // 如果当前时间小于上次生成时间，说明系统时钟回退了
  if (timestamp < lastTimestamp) {
    throw new Error('系统时钟回退，无法生成ID');
  }
  
  // 如果是同一毫秒内生成ID，则序列号递增
  if (timestamp === lastTimestamp) {
    sequence = (sequence + 1) & 0xFFF; // 序列号范围 0-4095
    // 如果序列号溢出，等待下一毫秒
    if (sequence === 0) {
      timestamp = waitNextMillis(lastTimestamp);
    }
  } else {
    // 不同毫秒，序列号重置为0
    sequence = 0;
  }
  
  lastTimestamp = timestamp;
  
  // 计算相对时间戳（从起始时间开始）
  const relativeTimestamp = timestamp - EPOCH;
  
  // 生成18位雪花ID
  // 时间戳(42位) + 机器ID(5位) + 序列号(12位) = 59位
  // 由于JavaScript的Number类型限制，我们需要使用BigInt
  const id = BigInt(relativeTimestamp) << 17n | BigInt(MACHINE_ID) << 12n | BigInt(sequence);
  
  // 确保ID是18位数字且不以0开头
  let idString = id.toString();
  
  // 如果ID长度不足18位，在前面补0
  if (idString.length < 18) {
    idString = idString.padStart(18, '0');
  }
  
  // 如果ID长度超过18位，取前18位
  if (idString.length > 18) {
    idString = idString.substring(0, 18);
  }
  
  // 确保ID不以0开头，如果以0开头则重新生成
  if (idString.startsWith('0')) {
    // 在ID前面添加1，确保不以0开头，然后截取18位
    idString = '1' + idString;
    if (idString.length > 18) {
      idString = idString.substring(0, 18);
    }
  }
  
  return idString;
}

/**
 * 等待下一毫秒
 * @param {number} lastTimestamp 上次时间戳
 * @returns {number} 新的时间戳
 */
function waitNextMillis(lastTimestamp) {
  let timestamp = Date.now();
  while (timestamp <= lastTimestamp) {
    timestamp = Date.now();
  }
  return timestamp;
}

/**
 * 验证雪花ID格式
 * @param {string} id 雪花ID
 * @returns {boolean} 是否为有效的18位雪花ID
 */
export function validateSnowflakeId(id) {
  if (!id || typeof id !== 'string') {
    return false;
  }
  
  // 检查长度是否为18位
  if (id.length !== 18) {
    return false;
  }
  
  // 检查是否只包含数字
  if (!/^\d{18}$/.test(id)) {
    return false;
  }
  
  // 检查是否以0开头（新规定：不允许以0开头）
  if (id.startsWith('0')) {
    return false;
  }
  
  // 尝试解析ID
  try {
    const parsed = parseSnowflakeId(id);
    return parsed !== null;
  } catch (error) {
    return false;
  }
}

/**
 * 获取当前机器ID
 * @returns {number} 机器ID
 */
export function getMachineId() {
  return MACHINE_ID;
}

/**
 * 获取起始时间戳
 * @returns {number} 起始时间戳
 */
export function getEpoch() {
  return EPOCH;
}

/**
 * 解析18位雪花ID
 * @param {string} id 18位雪花ID
 * @returns {Object} 解析结果
 */
export function parseSnowflakeId(id) {
  try {
    const numId = BigInt(id);
    
    // 解析各个部分
    const sequence = Number(numId & 0xFFFn); // 后12位是序列号
    const machineId = Number((numId >> 12n) & 0x1Fn); // 中间5位是机器ID
    const relativeTimestamp = Number(numId >> 17n); // 前42位是相对时间戳
    
    // 计算实际时间戳
    const timestamp = relativeTimestamp + EPOCH;
    
    return {
      timestamp: new Date(timestamp),
      machineId,
      sequence,
      relativeTimestamp,
      epoch: EPOCH
    };
  } catch (error) {
    console.error('解析雪花ID失败:', error);
    return null;
  }
} 